/* eslint-env worker */
// Vhall Stream Saver - Background Script
// 全局网络监听和流嗅探
// 尝试加载 HLS 下载器
try {
  importScripts('hls-downloader.js');
} catch (e) {
  console.warn('[Background] Failed to import HLS downloader:', e);
}

class VhallStreamDetector {
  constructor() {
    this.detectedStreams = new Map();
    this.streamCache = new Map(); // 流缓存，用于去重
    this.CACHE_DURATION = 5 * 60 * 1000; // 5分钟缓存时间
    this.nativeHostName = 'com.vhall.stream.saver';
    this.init();
  }

  init() {
    this.setupWebRequestListener();
    this.setupMessageHandlers();
    this.setupStorageCleanup();

    // 定期清理过期的流缓存
    setInterval(() => {
      this.cleanupExpiredCache();
    }, 60000); // 每分钟清理一次
  }

  // 设置网络请求监听器
  setupWebRequestListener() {
    // 监听 dispatch_replay API 调用
    chrome.webRequest.onBeforeRequest.addListener(
      (details) => {
        if (this.isVhallDispatchRequest(details.url)) {
          this.handleDispatchRequest(details);
        }
      },
      {
        urls: [
          '*://gslb.e.vhall.com/api/dispatch_replay*',
          '*://*.vhallyun.com/api/dispatch_replay*'
        ]
      },
      ['requestBody']
    );

    // 监听响应头获取 Referer
    chrome.webRequest.onBeforeSendHeaders.addListener(
      (details) => {
        if (this.isVhallDispatchRequest(details.url)) {
          this.captureRequestHeaders(details);
        }
      },
      {
        urls: [
          '*://gslb.e.vhall.com/api/dispatch_replay*',
          '*://*.vhallyun.com/api/dispatch_replay*'
        ]
      },
      ['requestHeaders']
    );

    // 监听响应获取 token 和流信息
    chrome.webRequest.onCompleted.addListener(
      (details) => {
        if (this.isVhallDispatchRequest(details.url)) {
          this.handleDispatchResponse(details);
        }
      },
      {
        urls: [
          '*://gslb.e.vhall.com/api/dispatch_replay*',
          '*://*.vhallyun.com/api/dispatch_replay*'
        ]
      },
      ['responseHeaders']
    );
  }

  // 判断是否为微吼 dispatch 请求
  isVhallDispatchRequest(url) {
    return url.includes('/api/dispatch_replay');
  }

  // 处理 dispatch 请求
  handleDispatchRequest(details) {
    console.log('[Vhall] Detected dispatch request:', details.url);

    // 存储请求信息
    const requestInfo = {
      url: details.url,
      tabId: details.tabId,
      timestamp: Date.now(),
      method: details.method
    };

    this.detectedStreams.set(details.requestId, requestInfo);
  }

  // 捕获请求头信息
  captureRequestHeaders(details) {
    const streamInfo = this.detectedStreams.get(details.requestId);
    if (!streamInfo) return;

    // 提取 Referer
    const refererHeader = details.requestHeaders?.find(
      header => header.name.toLowerCase() === 'referer'
    );

    if (refererHeader) {
      streamInfo.referer = refererHeader.value;
      console.log('[Vhall] Captured referer:', refererHeader.value);
    }

    this.detectedStreams.set(details.requestId, streamInfo);
  }

  // 处理 dispatch 响应
  async handleDispatchResponse(details) {
    const streamInfo = this.detectedStreams.get(details.requestId);
    if (!streamInfo) return;

    try {
      // 获取响应数据
      const response = await this.fetchDispatchResponse(details.url, streamInfo.referer);
      if (response && response.data) {
        await this.processStreamData(response.data, streamInfo);
      }
    } catch (error) {
      console.error('[Vhall] Error processing dispatch response:', error);
    }

    // 清理临时数据
    this.detectedStreams.delete(details.requestId);
  }

  // 获取 dispatch 响应数据
  async fetchDispatchResponse(url, referer) {
    try {
      const response = await fetch(url, {
        headers: {
          'Referer': referer || ''
        }
      });
      return await response.json();
    } catch (error) {
      console.error('[Vhall] Failed to fetch dispatch response:', error);
      return null;
    }
  }

  // 处理流数据
  async processStreamData(data, requestInfo) {
    console.log('[Vhall] Processing stream data:', JSON.stringify(data, null, 2));
    console.log('[Vhall] Request info:', JSON.stringify(requestInfo, null, 2));

    // 生成流的唯一标识符，基于 token + referer 组合
    const streamKey = this.generateStreamKey(data.token, requestInfo.referer);
    console.log('[Vhall] Generated stream key:', streamKey);

    // 检查是否为重复流
    if (this.isDuplicateStream(streamKey)) {
      console.log('[Vhall] Duplicate stream detected, skipping:', streamKey);
      return; // 重复流直接返回，不执行任何后续操作
    }

    // 规范化 hls_domainnames，选择优先线路并附加 token，同时保留所有线路选项
    const normalizedHls = {};
    const hlsOptions = {}; // 保存所有线路选项供UI选择
    try {
      const raw = data.hls_domainnames || {};
      for (const quality of Object.keys(raw)) {
        const arr = Array.isArray(raw[quality]) ? raw[quality] : [];

        // 选择默认线路（优先腾讯云，其次是线路1）
        const defaultPick = arr.find(e => e?.cdn_name === 'tx')
          || arr.find(e => typeof e?.line === 'string' && e.line.includes('1'))
          || arr[0];

        if (defaultPick) {
          const baseUrl = defaultPick.hls_domainname;
          const urlWithToken = baseUrl.includes('token=') ? baseUrl : `${baseUrl}?token=${data.token || ''}`;
          normalizedHls[quality] = urlWithToken;

          // 保存所有线路选项
          hlsOptions[quality] = arr.map(line => ({
            line: line.line || `线路${line.cdn_name}`,
            cdn_name: line.cdn_name,
            url: line.hls_domainname.includes('token=') ? line.hls_domainname : `${line.hls_domainname}?token=${data.token || ''}`
          }));
        }
      }
    } catch (e) {
      console.warn('[Vhall] Failed to normalize hls_domainnames:', e);
    }

    // 提取视频标题
    const videoTitle = await this.extractVideoTitle(requestInfo.referer, requestInfo.tabId);
    console.log('[Vhall] Extracted video title:', videoTitle);

    const streamData = {
      id: this.generateStreamId(),
      token: data.token,
      referer: requestInfo.referer,
      expired_datetime: data.expired_datetime,
      hls_domainnames: normalizedHls,
      hls_options: hlsOptions, // 添加线路选项
      video_title: videoTitle,
      page_url: requestInfo.referer,
      detected_at: new Date().toISOString(),
      tabId: requestInfo.tabId
    };

    console.log('[Vhall] Final stream data:', JSON.stringify(streamData, null, 2));

    // 将流添加到缓存（只有非重复流才会到达这里）
    this.addToStreamCache(streamKey, streamData);

    // 存储到 session storage（只有非重复流才会到达这里）
    const isNewStream = await this.saveStreamData(streamData);

    // 通知 popup 更新（只有真正的新流才通知）
    this.notifyPopupUpdate(streamData, isNewStream);

    console.log('[Vhall] Stream data processed and saved:', streamKey, 'isNewStream:', isNewStream);
  }

  // 生成流 ID
  generateStreamId() {
    return 'stream_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
  }

  // 生成流的唯一标识符
  generateStreamKey(token, referer) {
    if (!token || !referer) return null;
    // 对于华为云直播页面，token 可能每次都不同，所以主要基于 referer 来去重
    // 同时考虑 token 的前缀部分（如果存在的话）
    const baseReferer = referer.split('?')[0]; // 去掉查询参数
    console.log('[Vhall] Generating stream key for token:', token, 'referer:', baseReferer);
    return `${baseReferer}`;
  }

  // 检查是否为重复流
  isDuplicateStream(streamKey) {
    if (!streamKey) return false;

    const cachedStream = this.streamCache.get(streamKey);
    if (!cachedStream) return false;

    // 检查缓存是否过期
    const now = Date.now();
    if (now - cachedStream.timestamp > this.CACHE_DURATION) {
      // 缓存过期，删除并返回 false
      this.streamCache.delete(streamKey);
      return false;
    }

    return true;
  }

  // 将流添加到缓存
  addToStreamCache(streamKey, streamData) {
    if (!streamKey) return;

    this.streamCache.set(streamKey, {
      data: streamData,
      timestamp: Date.now()
    });

    // 定期清理过期缓存
    this.cleanupExpiredCache();
  }

  // 清理过期的缓存
  cleanupExpiredCache() {
    const now = Date.now();
    for (const [key, value] of this.streamCache.entries()) {
      if (now - value.timestamp > this.CACHE_DURATION) {
        this.streamCache.delete(key);
      }
    }
  }

  // 提取视频标题（优先使用 tabId，其次按 referer 查询，最后生成可读回退）
  async extractVideoTitle(referer, tabId) {
    // 1) 优先通过 tabId 获取标题（需要 tabs 权限）
    if (typeof tabId === 'number' && tabId >= 0) {
      try {
        const tab = await chrome.tabs.get(tabId);
        if (tab && tab.title) {
          return tab.title;
        }
      } catch (e) {
        // 忽略错误，继续尝试其他方式
      }
    }

    // 2) 退化为按 URL 查询当前标签页标题
    if (referer) {
      try {
        const tabs = await chrome.tabs.query({ url: referer });
        if (tabs.length > 0) {
          return tabs[0].title || 'Unknown Video';
        }
      } catch (error) {
        console.error('[Vhall] Failed to extract video title:', error);
      }
    }

    // 3) 最终回退：用域名/路径生成一个可读标题
    try {
      if (referer) {
        const u = new URL(referer);
        const pathLast = u.pathname.split('/').filter(Boolean).pop();
        return `华为云直播回放 ${pathLast || u.hostname}`;
      }
    } catch (e) {
      // 忽略
    }

    return '华为云直播回放';
  }

  // 保存流数据
  async saveStreamData(streamData) {
    try {
      // 获取现有数据
      const result = await chrome.storage.session.get(['detectedStreams']);
      const streams = result.detectedStreams || [];

      // 检查是否已存在相同的流（基于 token + referer）
      const streamKey = this.generateStreamKey(streamData.token, streamData.referer);
      const existingIndex = streams.findIndex(stream =>
        this.generateStreamKey(stream.token, stream.referer) === streamKey
      );

      let isNewStream = false;

      if (existingIndex !== -1) {
        // 如果已存在，更新现有流的数据
        const existingStream = streams[existingIndex];
        existingStream.detected_at = streamData.detected_at;

        // 如果有新的 HLS 信息，也更新
        if (streamData.hls_domainnames && Object.keys(streamData.hls_domainnames).length > 0) {
          existingStream.hls_domainnames = streamData.hls_domainnames;
        }
        if (streamData.hls_options) {
          existingStream.hls_options = streamData.hls_options;
        }

        console.log('[Vhall] Updated existing stream:', streamKey);
        isNewStream = false;
      } else {
        // 添加新流数据
        streams.unshift(streamData);
        console.log('[Vhall] Added new stream:', streamKey);
        isNewStream = true;
      }

      // 限制最多保存 50 个流
      if (streams.length > 50) {
        streams.splice(50);
      }

      // 保存到 session storage
      await chrome.storage.session.set({ detectedStreams: streams });

      // 返回是否是新流
      return isNewStream;
    } catch (error) {
      console.error('[Vhall] Failed to save stream data:', error);
      return false;
    }
  }

  // 通知 popup 更新
  notifyPopupUpdate(streamData, isNewStream = false) {
    // 只有真正的新流才发送消息，避免重复通知
    if (isNewStream) {
      console.log('[Vhall] Notifying popup of new stream:', streamData.page_url);
      chrome.runtime.sendMessage({
        type: 'STREAM_DETECTED',
        data: streamData
      }).catch(() => {
        // Popup 可能未打开，忽略错误
      });
    } else {
      console.log('[Vhall] Skipping notification for existing stream:', streamData.page_url);
    }

    // 更新 badge（始终更新）
    this.updateBadge();
  }

  // 更新徽章
  async updateBadge() {
    try {
      const result = await chrome.storage.session.get(['detectedStreams']);
      const streams = result.detectedStreams || [];
      const count = streams.length;

      if (count > 0) {
        chrome.action.setBadgeText({ text: count.toString() });
        chrome.action.setBadgeBackgroundColor({ color: '#4CAF50' });
      } else {
        chrome.action.setBadgeText({ text: '' });
      }
    } catch (error) {
      console.error('[Vhall] Failed to update badge:', error);
    }
  }

  // 设置消息处理器
  setupMessageHandlers() {
    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      this.handleMessage(message, sender, sendResponse);
      return true; // 保持消息通道开放
    });
  }

  // 处理消息
  async handleMessage(message, sender, sendResponse) {
    try {
      switch (message.type) {
      case 'GET_DETECTED_STREAMS':
        await this.handleGetDetectedStreams(sendResponse);
        break;

      case 'CLEAR_DETECTED_STREAMS':
        await this.handleClearDetectedStreams(sendResponse);
        break;

      case 'START_DOWNLOAD':
        await this.handleStartDownload(message.data, sendResponse);
        break;

      case 'CHECK_NATIVE_HOST':
        await this.handleCheckNativeHost(sendResponse);
        break;

      case 'TEST_STREAM_PROCESSING':
        await this.handleTestStreamProcessing(message, sendResponse);
        break;

      default:
        sendResponse({ success: false, error: 'Unknown message type' });
      }
    } catch (error) {
      console.error('[Vhall] Error handling message:', error);
      sendResponse({ success: false, error: error.message });
    }
  }

  // 获取检测到的流
  async handleGetDetectedStreams(sendResponse) {
    const result = await chrome.storage.session.get(['detectedStreams']);
    sendResponse({
      success: true,
      data: result.detectedStreams || []
    });
  }

  // 清除检测到的流
  async handleClearDetectedStreams(sendResponse) {
    await chrome.storage.session.remove(['detectedStreams']);
    await this.updateBadge();
    sendResponse({ success: true });
  }

  // 开始下载
  async handleStartDownload(downloadData, sendResponse) {
    try {
      // 智能策略选择
      const strategy = await this.selectDownloadStrategy(downloadData);
      console.log('Selected download strategy:', strategy);

      switch (strategy) {
      case 'native':
        const nativeResult = await this.executeNativeDownload(downloadData);
        sendResponse(nativeResult);
        return;

      case 'hls':
        const hlsResult = await this.executeHLSDownload(downloadData);
        sendResponse(hlsResult);
        return;

      case 'command':
      default:
        const commandResult = this.generateDownloadCommand(downloadData);
        sendResponse(commandResult);
        return;
      }
    } catch (error) {
      console.error('[Vhall] Download failed:', error);
      sendResponse({
        success: false,
        error: error.message,
        fallback: 'command_copy'
      });
    }
  }

  /**
   * 智能选择下载策略
   * @param {Object} downloadData - 下载数据
   * @returns {string} 策略名称
   */
  async selectDownloadStrategy(downloadData) {
    // 检查用户偏好设置
    const settings = await this.getSettings();
    const preferredStrategy = settings?.preferredDownloadStrategy || 'auto';

    if (preferredStrategy !== 'auto') {
      return preferredStrategy;
    }

    // 自动策略选择逻辑

    // 1. 检查 Native Host 可用性
    const nativeAvailable = await this.checkNativeHostAvailability();

    // 2. 检测文件大小
    const fileSize = await this.estimateFileSize(downloadData);

    // 3. 检查网络条件
    const networkQuality = await this.assessNetworkQuality();

    // 4. 分析流类型
    const streamType = this.analyzeStreamType(downloadData);

    // 策略决策逻辑
    if (nativeAvailable && (fileSize > 100 * 1024 * 1024 || streamType === 'live')) {
      // 大文件或直播流优先使用 Native yt-dlp
      return 'native';
    }

    if (streamType === 'hls' && fileSize < 500 * 1024 * 1024 && networkQuality === 'good') {
      // 中小型 HLS 流且网络良好时使用内置下载器
      return 'hls';
    }

    if (nativeAvailable) {
      // 默认优先使用 Native yt-dlp
      return 'native';
    }

    if (streamType === 'hls') {
      // HLS 流使用内置下载器
      return 'hls';
    }

    // 最后降级到命令复制
    return 'command';
  }

  /**
   * 检查 Native Host 可用性
   */
  async checkNativeHostAvailability() {
    try {
      const settings = await this.getSettings();
      const message = { action: 'CHECK_YTDLP', data: { ytdlpPath: settings.ytdlpPath } };

      return new Promise((resolve) => {
        chrome.runtime.sendNativeMessage(
          this.nativeHostName,
          message,
          (response) => {
            if (chrome.runtime.lastError) {
              resolve(false);
            } else {
              resolve(!!(response && response.available));
            }
          }
        );
      });
    } catch (error) {
      console.warn('Native Host not available:', error);
      return false;
    }
  }

  /**
   * 获取设置
   */
  async getSettings() {
    try {
      const result = await chrome.storage.local.get(['vhallSettings']);
      return result.vhallSettings || {};
    } catch (error) {
      console.warn('Failed to get settings:', error);
      return {};
    }
  }

  /**
   * 估算文件大小
   * @param {Object} downloadData - 下载数据
   */
  async estimateFileSize(downloadData) {
    try {
      // 尝试 HEAD 请求获取 Content-Length
      const response = await fetch(downloadData.url, {
        method: 'HEAD',
        headers: downloadData.headers || {}
      });

      const contentLength = response.headers.get('content-length');
      if (contentLength) {
        return parseInt(contentLength);
      }

      // 如果是 HLS 流，尝试解析 M3U8 估算大小
      if (downloadData.url.includes('.m3u8')) {
        return await this.estimateHLSSize(downloadData);
      }

      // 默认估算值
      return 50 * 1024 * 1024; // 50MB
    } catch (error) {
      console.warn('Failed to estimate file size:', error);
      return 50 * 1024 * 1024; // 默认 50MB
    }
  }

  /**
   * 估算 HLS 流大小
   * @param {Object} downloadData - 下载数据
   */
  async estimateHLSSize(downloadData) {
    try {
      const response = await fetch(downloadData.url, {
        headers: downloadData.headers || {}
      });
      const m3u8Content = await response.text();

      // 解析分片数量和时长
      const lines = m3u8Content.split('\n');
      let totalDuration = 0;
      let segmentCount = 0;

      for (const line of lines) {
        if (line.startsWith('#EXTINF:')) {
          const duration = parseFloat(line.split(':')[1].split(',')[0]);
          totalDuration += duration;
          segmentCount++;
        }
      }

      // 估算码率 (假设平均 2Mbps)
      const estimatedBitrate = 2 * 1024 * 1024; // 2Mbps in bits
      const estimatedSize = (totalDuration * estimatedBitrate) / 8; // 转换为字节

      return Math.max(estimatedSize, segmentCount * 1024 * 1024); // 至少每个分片 1MB
    } catch (error) {
      console.warn('Failed to estimate HLS size:', error);
      return 100 * 1024 * 1024; // 默认 100MB
    }
  }

  /**
   * 评估网络质量
   */
  async assessNetworkQuality() {
    try {
      // 简单的延迟测试
      const startTime = Date.now();
      await fetch('https://www.google.com/favicon.ico', {
        method: 'HEAD',
        cache: 'no-cache'
      });
      const latency = Date.now() - startTime;

      if (latency < 100) return 'good';
      if (latency < 300) return 'medium';
      return 'poor';
    } catch (error) {
      console.warn('Failed to assess network quality:', error);
      return 'medium'; // 默认中等
    }
  }

  /**
   * 分析流类型
   * @param {Object} downloadData - 下载数据
   */
  analyzeStreamType(downloadData) {
    const url = downloadData.url.toLowerCase();

    if (url.includes('.m3u8')) {
      return 'hls';
    }

    if (url.includes('.mpd')) {
      return 'dash';
    }

    if (url.includes('live') || url.includes('stream')) {
      return 'live';
    }

    if (url.includes('.mp4') || url.includes('.mkv') || url.includes('.avi')) {
      return 'video';
    }

    return 'unknown';
  }

  /**
   * 执行 Native 下载
   * @param {Object} downloadData - 下载数据
   */
  async executeNativeDownload(downloadData) {
    try {
      const settings = await this.getSettings();
      const message = {
        action: 'DOWNLOAD_STREAM',
        data: {
          url: downloadData.url,
          outputPath: downloadData.outputPath,
          quality: downloadData.quality,
          headers: {
            Referer: downloadData.referer
          },
          ytdlpPath: settings.ytdlpPath,
          ytdlpArgs: settings.ytdlpArgs
        }
      };

      return new Promise((resolve) => {
        chrome.runtime.sendNativeMessage(
          this.nativeHostName,
          message,
          (response) => {
            if (chrome.runtime.lastError) {
              // 降级到 HLS 下载器
              this.executeHLSDownload(downloadData).then(resolve);
            } else {
              resolve({
                success: true,
                method: 'native',
                data: response
              });
            }
          }
        );
      });
    } catch (error) {
      console.error('Native download failed:', error);
      // 降级到 HLS 下载器
      return await this.executeHLSDownload(downloadData);
    }
  }

  /**
   * 执行 HLS 下载
   * @param {Object} downloadData - 下载数据
   */
  async executeHLSDownload(downloadData) {
    try {
      // 检查是否为 HLS 流
      if (!downloadData.url || !downloadData.url.includes('.m3u8')) {
        throw new Error('Not an HLS stream');
      }

      // 确认 HLS 下载器可用
      if (typeof HLSDownloader === 'undefined') {
        throw new Error('HLS downloader not available');
      }

      const downloader = new HLSDownloader();

      // 合并并注入 Referer 到请求头，确保 M3U8 与分片/密钥请求携带来源
      const hlsData = {
        ...downloadData,
        headers: {
          ...(downloadData.headers || {}),
          Referer: downloadData.referer
        }
      };

      return await new Promise((resolve) => {
        downloader.startDownload(
          hlsData,
          // 进度回调
          (progressInfo) => {
            try {
              chrome.runtime.sendMessage({
                type: 'DOWNLOAD_PROGRESS',
                data: {
                  downloadId: hlsData.id,
                  status: 'downloading',
                  ...progressInfo,
                  url: hlsData.url,
                  title: hlsData.title || 'video.ts'
                }
              });
            } catch (e) {
              // Popup 未打开时会失败，忽略即可
            }
          },
          // 完成回调
          (completeInfo) => {
            try {
              chrome.runtime.sendMessage({
                type: 'DOWNLOAD_PROGRESS',
                data: {
                  downloadId: hlsData.id,
                  status: 'completed',
                  progress: 100,
                  url: hlsData.url,
                  title: hlsData.title || 'video.ts',
                  totalSize: completeInfo.totalSize
                }
              });
            } catch (e) {
              // Popup 未打开时可能抛错，安全忽略
            }
            resolve({
              success: true,
              method: 'hls',
              data: completeInfo
            });
          },
          // 错误回调
          (error) => {
            try {
              chrome.runtime.sendMessage({
                type: 'DOWNLOAD_PROGRESS',
                data: {
                  downloadId: hlsData.id,
                  status: 'failed',
                  url: hlsData.url,
                  title: hlsData.title || 'video.ts'
                }
              });
            } catch (e) {
              // Popup 未打开时可能抛错，安全忽略
            }
            resolve({
              success: false,
              error: error.message,
              fallback: 'command_copy'
            });
          }
        );
      });
    } catch (error) {
      console.error('HLS download failed:', error);
      // 最后降级到命令复制
      return this.generateDownloadCommand(downloadData);
    }
  }

  /**
   * 生成下载命令
   * @param {Object} downloadData - 下载数据
   */
  generateDownloadCommand(downloadData) {
    const command = `yt-dlp --referer "${downloadData.referer}" "${downloadData.url}"`;

    return {
      success: true,
      method: 'command',
      command: command,
      message: 'Download command generated. Please copy and run in terminal.'
    };
  }



  // 检查 Native Host
  async handleCheckNativeHost(sendResponse) {
    try {
      const settings = await this.getSettings();
      const message = { action: 'CHECK_YTDLP', data: { ytdlpPath: settings.ytdlpPath } };
      chrome.runtime.sendNativeMessage(
        this.nativeHostName,
        message,
        (response) => {
          if (chrome.runtime.lastError) {
            sendResponse({ success: false, available: false, error: chrome.runtime.lastError.message });
          } else {
            sendResponse({ success: true, available: !!(response && response.available), data: response });
          }
        }
      );
    } catch (error) {
      sendResponse({ success: false, available: false, error: error.message });
    }
  }

  // 测试流数据处理
  async handleTestStreamProcessing(message, sendResponse) {
    console.log('[Vhall] Handling test stream processing request');
    try {
      const { apiResponse, requestInfo } = message;
      console.log('[Vhall] Test API response:', apiResponse);
      console.log('[Vhall] Test request info:', requestInfo);

      if (apiResponse && apiResponse.data && requestInfo) {
        // 直接调用 processStreamData 来测试数据处理
        await this.processStreamData(apiResponse.data, requestInfo);

        sendResponse({
          success: true,
          message: 'Test data processed successfully',
          processed: true
        });
      } else {
        sendResponse({
          success: false,
          error: 'Invalid test data provided',
          processed: false
        });
      }
    } catch (error) {
      console.error('[Vhall] Test stream processing failed:', error);
      sendResponse({
        success: false,
        error: error.message,
        processed: false
      });
    }
  }

  // 设置存储清理
  setupStorageCleanup() {
    // 每小时清理一次过期数据
    setInterval(() => {
      this.cleanupExpiredStreams();
    }, 60 * 60 * 1000);
  }

  // 清理过期流数据
  async cleanupExpiredStreams() {
    try {
      const result = await chrome.storage.session.get(['detectedStreams']);
      const streams = result.detectedStreams || [];

      const now = new Date();
      const validStreams = streams.filter(stream => {
        if (!stream.expired_datetime) return true;

        const expiredTime = new Date(stream.expired_datetime);
        return expiredTime > now;
      });

      if (validStreams.length !== streams.length) {
        await chrome.storage.session.set({ detectedStreams: validStreams });
        await this.updateBadge();
        console.log('[Vhall] Cleaned up expired streams');
      }
    } catch (error) {
      console.error('[Vhall] Failed to cleanup expired streams:', error);
    }
  }
}

// 初始化流检测器
const streamDetector = new VhallStreamDetector();

console.log('[Vhall] Background script loaded successfully');
